package com.cskaoyan.javase.object._1getclass;

/**
 * Object类当中的getClass方法
 * 1.方法的声明
 *  public final native Class<?> getClass();
 *  首先该方法的访问权限修饰符是public,访问权限不用担心
 *  它是final修饰的,表示该方法无法重写
 *  native表示它是一个本地方法,所以不需要关注它的实现,只关心作用即可
 *  Class是方法的返回值类型,表示该方法返回一个Class对象
 *  <?>这是Java泛型,关于泛型在集合当中会详细说明,这里略过它.因为Java的泛型是伪泛型,对程序的运行没有影响,仅影响编译.
 *  这个方法不需要参数,是无参的.
 *
 * 2.作用
 *  该方法的作用是返回一个该对象(调用该方法的一个对象)的Class对象
 *  什么是Class对象?它是怎么来的?它的作用是什么?
 *  Class对象是类的运行时对象
 *  它是在类加载过程中，JVM自动创建的
 *  它的作用在程序的运行期间，帮助程序员获取类型信息
 *  于是，现在：
 *  在程序的运行期间，JVM能够了解类型信息，程序员也能够了解类型信息。
 *
 *  3.细节问题：
 *       a.Class对象是JVM创建的,不是getClass方法创建.getClass方法只不过是让引用指向Class对象
 *          有引用后,我们才可以操作Class对象
 *       b.某个类的类加载在程序一次运行期间,仅有一次.所以运行时Class对象,也只有一个
 *          这是非常有用的:
 *      如果两个引用调用getClass的返回值用"=="连接返回结果true,这表示两个引用指向的对象,一定是同种类型的对象(是严格的同种类型,父子类对象也不能)
 *      相反,如果两个引用调用getClass的返回值用"=="连接,返回结果false.这表示两个引用指向的对象,一定不是同种类型的对象
 *
 * 4.类对象 = Class对象
 * 5.Class对象是反射的基础,反射虽然听起来很牛逼,但实际上就是Class类的API学习
 *
 * @since 09:46
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        Class stuClazz = s.getClass();
        Student s2 = new Student();
        Class stuClazz2 = s2.getClass();
        // true
        System.out.println(stuClazz == stuClazz2);
        Teacher t = new Teacher();
        Class teacherClazz = t.getClass();
        // false
        System.out.println(stuClazz == teacherClazz);

        StudentSon ss = new StudentSon();
        Class sonClazz = ss.getClass();
        // false
        System.out.println(sonClazz == stuClazz);

        // 获取类的全限定类名
        System.out.println(sonClazz.getName());
        // 获取类的简单类名(不带包名)
        System.out.println(sonClazz.getSimpleName());
    }
}

class Student {
}

class Teacher {
}
class StudentSon extends Student{}